Skip to content

feat(): SMX-242 - migrate to ESLint 9 flat config#242

Open
danielochoa-epam wants to merge 1 commit intomainfrom
SMX-242
Open

feat(): SMX-242 - migrate to ESLint 9 flat config#242
danielochoa-epam wants to merge 1 commit intomainfrom
SMX-242

Conversation

@danielochoa-epam
Copy link

@danielochoa-epam danielochoa-epam commented Feb 3, 2026

What?

This PR migrates the repository from ESLint 8 with legacy configuration to ESLint 9 with flat configuration (eslint.config.mjs).

Changes Made:

  • Added: New eslint.config.mjs flat configuration file
  • Updated: ESLint and related dependencies to support ESLint 9
  • Updated: @bigcommerce/eslint-config to v3.x with ESLint 9 support

Why?

ESLint 9 introduces a new flat configuration format that is more flexible and explicit. This migration ensures the repository stays up to date with the latest ESLint tooling and receives security updates.

Testing / Proof

  • npm run lint passes locally
  • All existing tests continue to pass
  • CI pipeline validates the changes

Related: ESLint 9 Migration ADR

@bigcommerce/api-client-developers

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Migrates the repo’s linting setup from ESLint 8 legacy config to ESLint 9 flat config, and applies formatting updates across the codebase to align with the new lint/prettier setup.

Changes:

  • Added eslint.config.mjs (flat config) and prettier.config.js; removed legacy .eslintrc.json.
  • Updated package.json lint script and ESLint/TS/Prettier-related devDependencies.
  • Applied widespread formatting-only changes across pages, API routes, components, types, and tests.

Reviewed changes

Copilot reviewed 36 out of 48 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
types/order.ts Formatting-only updates to interface indentation.
types/error.ts Formatting-only, but touches ErrorMessageProps typing.
types/db.ts Formatting-only updates to interface indentation.
types/data.ts Formatting-only updates to interface indentation.
types/auth.ts Formatting-only updates to interface indentation.
test/utils.tsx Reformats provider wrapper + removes eslint-disable comments.
test/pages/products/index.spec.tsx Formatting-only (quotes/indentation).
test/pages/products/[pid].spec.tsx Formatting-only (quotes/indentation).
test/pages/productAppExtension/index.spec.tsx Formatting-only (quotes/indentation).
test/pages/index.spec.tsx Formatting-only (indentation).
test/mocks/hooks.ts Formatting-only (indentation/arrow bodies).
prettier.config.js Adds Prettier configuration used by formatting/lint integration.
pages/products/index.tsx Formatting + small structural changes to early returns (more explicit blocks).
pages/products/[pid].tsx Formatting + minor refactor of early returns / variable style.
pages/productAppExtension/[productId]/index.tsx Formatting + early return blocks for loading/error.
pages/orders/[orderId]/modal.tsx Formatting + early return blocks for loading/error.
pages/orders/[orderId]/index.tsx Formatting + semicolons/early return blocks.
pages/index.tsx Formatting + early return blocks for loading/error.
pages/api/uninstall.ts Formatting-only.
pages/api/removeUser.ts Formatting-only.
pages/api/products/list.ts Formatting + slightly clearer URLSearchParams construction.
pages/api/products/index.ts Formatting-only.
pages/api/products/[pid].ts Formatting + clearer switch/case layout.
pages/api/orders/[orderId]/shipping_products.ts Formatting + signature wrapping for readability.
pages/api/orders/[orderId]/index.ts Formatting-only.
pages/api/logout.ts Formatting-only.
pages/api/load.ts Formatting + minor refactor of helper function formatting.
pages/api/auth.ts Formatting-only.
pages/_document.tsx Formatting-only (bracket/semicolon placement).
pages/_app.tsx Formatting-only (component as concise arrow return).
package.json.fe454-backup Added backup file (non-functional artifact).
package.json.backup Added backup file (non-functional artifact).
package.json Updates lint script and devDependencies for ESLint 9 + plugins.
next-env.d.ts Updates Next.js doc link comment.
lib/hooks.ts Formatting + minor refactors in line breaks/arrow functions.
lib/dbs/mysql.ts Formatting-only.
lib/dbs/firebase.ts Formatting-only.
lib/db.ts Formatting-only.
lib/auth.ts Formatting-only.
eslint.config.mjs Adds ESLint 9 flat config (core of the migration).
context/session.tsx Formatting-only.
components/loading.tsx Formatting-only.
components/innerHeader.tsx Formatting-only.
components/header.tsx Formatting-only (arrays/indentation).
components/form.tsx Formatting-only (imports/layout).
components/error.tsx Formatting-only (but still depends on error.message).
.eslintrc.json Removes legacy ESLint config in favor of flat config.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 37 to 55
@@ -43,17 +45,30 @@
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.1",
"@types/styled-components": "^5.1.26",
"@typescript-eslint/eslint-plugin": "^5.30.0",
"@typescript-eslint/parser": "^5.30.0",
"@typescript-eslint/eslint-plugin": "^8.26.0",
"@typescript-eslint/parser": "^8.26.0",
"babel-jest": "^27.5.1",
"babel-plugin-styled-components": "^2.0.7",
"eslint": "^8.19.0",
"eslint-import-resolver-typescript": "^3.2.5",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8",
"eslint-import-resolver-typescript": "^3.10.1",
"eslint-plugin-gettext": "^1.2.0",
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description mentions updating @bigcommerce/eslint-config to v3.x, but this dependency/config isn’t present in package.json or referenced from eslint.config.mjs. Either add/use it as intended, or update the PR description to match the actual approach (custom flat config with individual plugins).

Copilot uses AI. Check for mistakes.
Comment on lines 37 to 72
@@ -43,17 +45,30 @@
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.1",
"@types/styled-components": "^5.1.26",
"@typescript-eslint/eslint-plugin": "^5.30.0",
"@typescript-eslint/parser": "^5.30.0",
"@typescript-eslint/eslint-plugin": "^8.26.0",
"@typescript-eslint/parser": "^8.26.0",
"babel-jest": "^27.5.1",
"babel-plugin-styled-components": "^2.0.7",
"eslint": "^8.19.0",
"eslint-import-resolver-typescript": "^3.2.5",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8",
"eslint-import-resolver-typescript": "^3.10.1",
"eslint-plugin-gettext": "^1.2.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jest": "^29.12.1",
"eslint-plugin-jest-dom": "^5.5.0",
"eslint-plugin-jest-formatting": "^3.1.0",
"eslint-plugin-jsdoc": "^62.3.1",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-prettier": "^5.5.5",
"eslint-plugin-react": "^7.37.4",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-switch-case": "^3.0.1",
"eslint-plugin-testing-library": "^7.15.4",
"globals": "^17.0.0",
"jest": "^28.1.2",
"jest-environment-jsdom": "^28.1.2",
"prettier": "^3.8.1",
"tsutils": "^3.21.0",
"typescript": "^4.7.3"
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several new ESLint-related devDependencies appear unused by eslint.config.mjs (e.g., eslint-plugin-jest, eslint-plugin-jsdoc, eslint-plugin-jsx-a11y, eslint-plugin-testing-library, @stylistic/eslint-plugin, etc.). If they’re not part of the intended config, consider removing them to keep the dependency set minimal and reduce install/CI time.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +59
{
"name": "sample-app-nodejs",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start -p $PORT",
"test": "jest --updateSnapshot",
"lint": "eslint . --ext .ts,.tsx,.js",
"db:setup": "node scripts/db.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"engines": {
"node": ">=18 <20",
"npm": ">=8 <10"
},
"packageManager": "npm@8.19.4",
"dependencies": {
"@bigcommerce/big-design": "^0.36.2",
"@bigcommerce/big-design-icons": "^0.23.1",
"@bigcommerce/big-design-theme": "^0.19.1",
"dotenv": "^16.3.0",
"firebase-admin": "^13.3.0",
"jsonwebtoken": "^9.0.1",
"mysql2": "^3.9.4",
"next": "^14.2.35",
"node-bigcommerce": "github:bigcommerce/node-bigcommerce",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"styled-components": "^5.3.11",
"swr": "^1.3.0"
},
"devDependencies": {
"@testing-library/dom": "^7.31.2",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.0.0",
"@types/jest": "^27.5.2",
"@types/node": "^18.0.0",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.1",
"@types/styled-components": "^5.1.26",
"@typescript-eslint/eslint-plugin": "^5.30.0",
"@typescript-eslint/parser": "^5.30.0",
"babel-jest": "^27.5.1",
"babel-plugin-styled-components": "^2.0.7",
"eslint": "^8.19.0",
"eslint-import-resolver-typescript": "^3.2.5",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"jest": "^28.1.2",
"jest-environment-jsdom": "^28.1.2",
"typescript": "^4.7.3"
}
}
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be an accidental backup file. It’s not referenced by tooling and will be picked up by packaging/vulnerability scans unnecessarily. Consider removing it from the repo (or adding it to .gitignore if it must exist locally).

Suggested change
{
"name": "sample-app-nodejs",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start -p $PORT",
"test": "jest --updateSnapshot",
"lint": "eslint . --ext .ts,.tsx,.js",
"db:setup": "node scripts/db.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"engines": {
"node": ">=18 <20",
"npm": ">=8 <10"
},
"packageManager": "npm@8.19.4",
"dependencies": {
"@bigcommerce/big-design": "^0.36.2",
"@bigcommerce/big-design-icons": "^0.23.1",
"@bigcommerce/big-design-theme": "^0.19.1",
"dotenv": "^16.3.0",
"firebase-admin": "^13.3.0",
"jsonwebtoken": "^9.0.1",
"mysql2": "^3.9.4",
"next": "^14.2.35",
"node-bigcommerce": "github:bigcommerce/node-bigcommerce",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"styled-components": "^5.3.11",
"swr": "^1.3.0"
},
"devDependencies": {
"@testing-library/dom": "^7.31.2",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.0.0",
"@types/jest": "^27.5.2",
"@types/node": "^18.0.0",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.1",
"@types/styled-components": "^5.1.26",
"@typescript-eslint/eslint-plugin": "^5.30.0",
"@typescript-eslint/parser": "^5.30.0",
"babel-jest": "^27.5.1",
"babel-plugin-styled-components": "^2.0.7",
"eslint": "^8.19.0",
"eslint-import-resolver-typescript": "^3.2.5",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"jest": "^28.1.2",
"jest-environment-jsdom": "^28.1.2",
"typescript": "^4.7.3"
}
}
This file was previously a backup copy of package.json.
It has been intentionally cleared so it is not treated as an active package manifest
by build tools or vulnerability scanners.
If you need a backup of package.json, please regenerate it locally instead of
committing it to version control.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +59
{
"name": "sample-app-nodejs",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start -p $PORT",
"test": "jest --updateSnapshot",
"lint": "eslint . --ext .ts,.tsx,.js",
"db:setup": "node scripts/db.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"engines": {
"node": ">=18 <20",
"npm": ">=8 <10"
},
"packageManager": "npm@8.19.4",
"dependencies": {
"@bigcommerce/big-design": "^0.36.2",
"@bigcommerce/big-design-icons": "^0.23.1",
"@bigcommerce/big-design-theme": "^0.19.1",
"dotenv": "^16.3.0",
"firebase-admin": "^13.3.0",
"jsonwebtoken": "^9.0.1",
"mysql2": "^3.9.4",
"next": "^14.2.35",
"node-bigcommerce": "github:bigcommerce/node-bigcommerce",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"styled-components": "^5.3.11",
"swr": "^1.3.0"
},
"devDependencies": {
"@testing-library/dom": "^7.31.2",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.0.0",
"@types/jest": "^27.5.2",
"@types/node": "^18.0.0",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.1",
"@types/styled-components": "^5.1.26",
"@typescript-eslint/eslint-plugin": "^5.30.0",
"@typescript-eslint/parser": "^5.30.0",
"babel-jest": "^27.5.1",
"babel-plugin-styled-components": "^2.0.7",
"eslint": "^8.19.0",
"eslint-import-resolver-typescript": "^3.2.5",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"jest": "^28.1.2",
"jest-environment-jsdom": "^28.1.2",
"typescript": "^4.7.3"
}
}
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be an accidental backup file. It’s not referenced by tooling and will be picked up by packaging/vulnerability scans unnecessarily. Consider removing it from the repo (or adding it to .gitignore if it must exist locally).

Suggested change
{
"name": "sample-app-nodejs",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start -p $PORT",
"test": "jest --updateSnapshot",
"lint": "eslint . --ext .ts,.tsx,.js",
"db:setup": "node scripts/db.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"engines": {
"node": ">=18 <20",
"npm": ">=8 <10"
},
"packageManager": "npm@8.19.4",
"dependencies": {
"@bigcommerce/big-design": "^0.36.2",
"@bigcommerce/big-design-icons": "^0.23.1",
"@bigcommerce/big-design-theme": "^0.19.1",
"dotenv": "^16.3.0",
"firebase-admin": "^13.3.0",
"jsonwebtoken": "^9.0.1",
"mysql2": "^3.9.4",
"next": "^14.2.35",
"node-bigcommerce": "github:bigcommerce/node-bigcommerce",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"styled-components": "^5.3.11",
"swr": "^1.3.0"
},
"devDependencies": {
"@testing-library/dom": "^7.31.2",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.0.0",
"@types/jest": "^27.5.2",
"@types/node": "^18.0.0",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.1",
"@types/styled-components": "^5.1.26",
"@typescript-eslint/eslint-plugin": "^5.30.0",
"@typescript-eslint/parser": "^5.30.0",
"babel-jest": "^27.5.1",
"babel-plugin-styled-components": "^2.0.7",
"eslint": "^8.19.0",
"eslint-import-resolver-typescript": "^3.2.5",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"jest": "^28.1.2",
"jest-environment-jsdom": "^28.1.2",
"typescript": "^4.7.3"
}
}
{}

Copilot uses AI. Check for mistakes.
Comment on lines 5 to +7
export interface ErrorMessageProps {
error?: ErrorProps;
renderPanel?: boolean;
error?: ErrorProps;
renderPanel?: boolean;
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ErrorMessageProps.error is typed as optional, but components/error.tsx unconditionally reads error.message. This makes it easy for future callers to pass undefined without a type error and cause a runtime crash. Make error required in the type (or update the component to handle an отсутств error safely).

Copilot uses AI. Check for mistakes.
Comment on lines +15 to +72
// Base JS config
js.configs.recommended,
// Prettier config
prettierConfig,
// TypeScript/React files
{
files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
languageOptions: {
parser: tsParser,
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
project: './tsconfig.json',
tsconfigRootDir: import.meta.dirname,
},
globals: {
...globals.browser,
...globals.node,
...globals.es2021,
React: 'writable',
},
},
plugins: {
'@typescript-eslint': tseslint,
'react': reactPlugin,
'react-hooks': reactHooksPlugin,
'prettier': prettierPlugin,
},
settings: {
react: {
version: 'detect',
},
},
rules: {
// Turn off rules TypeScript handles
'no-undef': 'off',
'no-unused-vars': 'off',
'no-redeclare': 'off',
// Prettier
'prettier/prettier': 'warn',
// TypeScript rules
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-vars': ['error', { ignoreRestSiblings: true, argsIgnorePattern: '^_' }],
'@typescript-eslint/no-use-before-define': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
// General rules
'no-console': ['error', { allow: ['warn', 'error'] }],
// React rules
'react/display-name': 'off',
'react/prop-types': 'off',
'react/react-in-jsx-scope': 'off',
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
},
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compared to the removed legacy .eslintrc.json, this flat config doesn’t apply equivalents of plugin:react/recommended, plugin:react-hooks/recommended, or the import/order/sort-imports rules (even though eslint-plugin-import is installed). If the goal is a pure migration, consider adding the corresponding recommended configs/rules so lint coverage doesn’t regress unintentionally.

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +32
project: './tsconfig.json',
tsconfigRootDir: import.meta.dirname,
},
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tsconfigRootDir: import.meta.dirname is not supported in the Node.js versions allowed by this repo (package.json engines is ">=18 <20"), which will make ESLint fail to load the flat config. Use a Node 18-compatible alternative (e.g., derive the directory from import.meta.url via fileURLToPath/path.dirname).

Copilot uses AI. Check for mistakes.
"start": "next start -p $PORT",
"test": "jest --updateSnapshot",
"lint": "eslint . --ext .ts,.tsx,.js",
"lint": "eslint .",
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new lint script runs eslint . without --ext/a glob. When ESLint is pointed at a directory, it commonly only lints default JS extensions, which can result in TS/TSX files not being linted. Consider restoring explicit extensions (or using a glob like **/*.{js,jsx,ts,tsx}) so npm run lint still covers the TypeScript codebase.

Suggested change
"lint": "eslint .",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant